//
//  CYWebViewController.m
//  cyjf
//
//  Created by tauCross on 2017/5/23.
//  Copyright © 2017年 Auto Financing. All rights reserved.
//

#import "CYWebViewController.h"

#import "CYWebViewPlugin.h"
#import "CYFullScreenWebView.h"



@interface CYWebViewController ()<WKUIDelegate, WKNavigationDelegate>

@property(nonatomic, strong)CYWebViewPlugin *plugin;
@property(nonatomic, assign)BOOL backed;
@property(nonatomic, strong)UIProgressView *progressView;
@property(nonatomic, strong)NSArray *jsNames;

@end


@implementation CYWebViewController

- (void)dealloc
{
    for(NSString *name in self.jsNames)
    {
        [self.webView.configuration.userContentController removeScriptMessageHandlerForName:name];
    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.navigationItem.title = self.defaultTitle.length ? self.defaultTitle : @"加载中...";
    
    self.plugin = [[CYWebViewPlugin alloc] init];
    self.plugin.webViewController = self;
    
    self.jsNames = [self.plugin supportActions];
    
    self.webView = [[CYFullScreenWebView alloc] initWithFrame:CGRectZero configuration:[self webViewConfiguration]];
    self.webView.UIDelegate = self;
    self.webView.navigationDelegate = self;
    [self.view addSubview:self.webView];
    
    self.progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
    self.progressView.userInteractionEnabled = NO;
    self.progressView.alpha = 0;
    self.progressView.progress = 0;
    [self.view addSubview:self.progressView];
    @weakify(self);
    [[TCRACObserve(self.webView, estimatedProgress) takeUntil:self.rac_willDeallocSignal] subscribeNext:^(id x) {
        @strongify(self);
        [self.progressView setProgress:[x doubleValue] animated:YES];
    }];
    
    [self updateNavigationButton];
    
    NSString *url = self.url;
    [self.webView loadRequest:[NSURLRequest requestWithURL:url.tc_url]];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.navigationController setNavigationBarHidden:NO animated:YES];
}

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    self.webView.frame = self.view.bounds;
    
    self.progressView.width = self.webView.width;
    self.progressView.left = 0;
    self.progressView.top = 0;
}

#pragma mark - Actions
- (void)backAction
{
    if([self.webView canGoBack])
    {
        [self.webView goBack];
        self.backed = YES;
        [self updateNavigationButton];
    }
    else
    {
        [self closeAction];
    }
}

- (void)closeAction
{
    if(self.navigationController.viewControllers.count == 1)
    {
        [self.navigationController dismissViewControllerAnimated:YES completion:nil];
    }
    else
    {
        [self.navigationController popViewControllerAnimated:YES];
    }
}

#pragma mark - WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{
    UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }];
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:alertAction];
    [self presentViewController:alertController animated:YES completion:nil];
}

- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler
{
    UIAlertAction *alertActionCancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }];
    UIAlertAction *alertActionOK = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }];
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:alertActionCancel];
    [alertController addAction:alertActionOK];
    [self presentViewController:alertController animated:YES completion:nil];
}

- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler
{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:nil preferredStyle:UIAlertControllerStyleAlert];
    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.placeholder = defaultText;
    }];
    [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        UITextField *textField = alertController.textFields.firstObject;
        completionHandler(textField.text);
    }]];
    [self presentViewController:alertController animated:YES completion:nil];
}

#pragma mark - WKNavigationDelegate
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
    @weakify(self);
    [UIView animateWithDuration:0.25
                     animations:^{
                         @strongify(self);
                         self.progressView.alpha = 1;
                     }];
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    @weakify(self);
    [UIView animateWithDuration:0.25
                     animations:^{
                         @strongify(self);
                         self.progressView.alpha = 0;
                     }];
    [self updateNavigationButton];
}

- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
    @weakify(self);
    [UIView animateWithDuration:0.25
                     animations:^{
                         @strongify(self);
                         self.progressView.alpha = 0;
                     }];
    [self updateNavigationButton];
}

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
{
    @weakify(self);
    [UIView animateWithDuration:0.25
                     animations:^{
                         @strongify(self);
                         self.progressView.alpha = 0;
                     }];
    [self updateNavigationButton];
}

#pragma mark - Private Method
- (void)updateNavigationButton
{
    NSMutableArray *buttonItems = [NSMutableArray array];
    if(self.navigationController.viewControllers.count == 1)
    {
        if(self.webView.canGoBack)
        {
            {
                UIImage *image = [CYImage(@"public_nav_back") imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
                UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(backAction)];
                [buttonItems addObject:item];
            }
            {
                UIImage *image = [CYImage(@"public_nav_close") imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
                UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(closeAction)];
                [buttonItems addObject:item];
            }

        }
        else
        {
            UIImage *image = [CYImage(@"public_nav_close") imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
            UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(closeAction)];
            [buttonItems addObject:item];
        }
    }
    else
    {
        {
            UIImage *image = [CYImage(@"public_nav_back") imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
            UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(backAction)];
            [buttonItems addObject:item];
        }
        if(self.backed)
        {
            UIImage *image = [CYImage(@"public_nav_close") imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
            UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(closeAction)];
            [buttonItems addObject:item];
        }
    }
    self.navigationItem.leftBarButtonItems = buttonItems;
}

- (WKWebViewConfiguration *)webViewConfiguration
{
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    for(NSString *name in self.jsNames)
    {
        [configuration.userContentController addScriptMessageHandler:self.plugin name:name];
    }
    {
        WKUserScript *titleScript = [[WKUserScript alloc] initWithSource:@"CYJFBridge.execute('setNavigationTitle', document.title, null);" injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO];
        [configuration.userContentController addUserScript:titleScript];
    }
    {
        WKUserScript *disableActionScript = [[WKUserScript alloc] initWithSource:@"document.documentElement.style.webkitTouchCallout='none';" injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO];
        [configuration.userContentController addUserScript:disableActionScript];
    }
    {
        NSString *jsbridge = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"CYJFBridge" ofType:@"js"] encoding:NSUTF8StringEncoding error:nil];
        WKUserScript *bridgeScript = [[WKUserScript alloc] initWithSource:jsbridge injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
        [configuration.userContentController addUserScript:bridgeScript];
    }
    {
        WKUserScript *titleScript = [[WKUserScript alloc] initWithSource:@"if(typeof(webviewOnReady) === 'function') webviewOnReady();" injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO];
        [configuration.userContentController addUserScript:titleScript];
    }
    return configuration;
}

@end
